package com.example.mybatis_demo.excel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.function.Function;

/**
 * 合并策略
 * @author dzh
 * @since 2025/4/17
 */
public class MyMergeStrategy extends AbstractMergeStrategy {
    // 根据数据的下标判断是否需要合并行
    private final Function<Integer, Boolean> eqBefore;
    // 根据列序号判断该列列是否需要行合并，从0开始
    private final Function<Integer, Boolean> columnNeedMerge;

    public MyMergeStrategy(Function<Integer, Boolean> eqBefore, Function<Integer, Boolean> columnNeedMerge) {
        this.eqBefore = eqBefore;
        this.columnNeedMerge = columnNeedMerge;
    }
    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (relativeRowIndex == null || relativeRowIndex <= 1) {
            return;
        }
        if (!columnNeedMerge.apply(cell.getColumnIndex())) {
            return;
        }
        if (!eqBefore.apply(relativeRowIndex) && eqBefore.apply(relativeRowIndex - 1)) {
            int endRow = cell.getRowIndex() - 1;
            int firstRow = getFirstRow(endRow, relativeRowIndex - 1);
            CellRangeAddress rangeAddress = new CellRangeAddress(firstRow, endRow, cell.getColumnIndex(), cell.getColumnIndex());
            sheet.addMergedRegion(rangeAddress);
        }
    }

    private int getFirstRow(int rowIndex, int dataIndex) {
        if (dataIndex == 0) {
            return rowIndex;
        }
        if (this.eqBefore.apply(dataIndex)) {
            return getFirstRow(rowIndex - 1, dataIndex - 1);
        }
        return rowIndex;
    }
}
